﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Collections;
using System.Text.RegularExpressions;

namespace mlnx_os_sysdump_analyzer
{
    class ChassisInfo
    {
        ArrayList items = new ArrayList();
        private bool KEEP_RUNNING;
        public string interfaceMgmt = "";
        public string partNumber = "";
        public string mgmtStatus = "";
        public bool timeouts = false;
        public string localRole = ""; // from show chassis ha
        //
        //----------------------------------------------------
        //
        public ChassisInfo(ref bool KEEP_RUNNING)
        {
            this.KEEP_RUNNING = KEEP_RUNNING;   
        }
        //
        //----------------------------------------------------
        //
        public ArrayList getChassisItemsInfo()
        {
            return items;
        }
        //
        //----------------------------------------------------
        //
        public void scanHardwarInfo(object param)
        {
            string srcFilePath = (string)param;
            if (srcFilePath == null)
                return;
            StreamReader sr = new StreamReader(srcFilePath);
            bool scanInterfaceMgmt = false;
            try
            {
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    if (sr.ReadLine().Contains("chassis info"))
                    {
                        break;
                    }
                }
                int counter = 0;
                int healthRepCounter = 0; /// counter for the health report output, will use it to make sure that the
										  /// output of "|    HEALTH REPORT     |" will be displayed along with output of "| ALERTS CONFIGURATION |"
                Item tmpItem = new Item();
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    try
                    {
                        // read line
                        string line = sr.ReadLine();

                        if (line.Contains("timed out after"))
                        {
                            timeouts = true;
                        }
                        //
                        if (line.Contains("Management back end unavailable"))
                        {
                            mgmtStatus = "* ERROR: Management back end unavailable.  The switch continued with reduced functionality." + "\r\n\r\n";
                        }
                        //
                        if (line.Contains("port info"))
                        {
                            sr.Dispose();
                            return;
                        }
                        else
                        {
                            if (line.Contains("Unrecognized") || line.Contains("for help"))
                            {
                            }
                            else
                            {
                            	if (line.Contains("=========") && line.StartsWith("========="))
                                {
                                    if (tmpItem.itemName.Equals(""))
                                    {
                                        if (counter == 0)
                                        {
                                            counter++;
                                        }
                                    }
                                    else
                                    {
                                    	if (tmpItem.itemName.Equals("show health-report") && healthRepCounter <= 3)
                                    	{
                                    		healthRepCounter++;
                                    		tmpItem.content += line + "\r\n";
                                    		if (counter == 2)
                                    		{
                                    			counter++;
                                    		}
                                    	}
                                    	else
                                    	{
	                                        counter++;
	                                        if (counter == 4)
	                                        {
	                                            counter = 1;
	                                            items.Add(tmpItem);
	                                            tmpItem = new Item();
	                                        }
                                    	}
                                    }
                                }
                                else
                                {
                                    if (counter == 1 && !line.Equals(""))
                                    {
                                        if (tmpItem.itemName.Equals(""))
                                        {
                                            tmpItem = new Item();
                                            // 
                                            tmpItem.itemName = mapHeaderToCommand(line);
                                            tmpItem.content += tmpItem.itemName + "\r\n\r\n";
                                            tmpItem.content += line + "\r\n";
                                            counter++;
                                            if (!interfaceMgmt.Equals(""))
                                            {
                                                scanInterfaceMgmt = false;
                                            }
                                        }
                                    }
                                    else
                                    if (counter == 2)
                                    {
                                    }
                                    else
                                    if (counter == 3)
                                    {
                                        if (line.Contains("Interface mgmt") || line.Contains("Interface eth"))
                                        {
                                            scanInterfaceMgmt = true;
                                        }
                                        if (scanInterfaceMgmt)
                                        {
                                            interfaceMgmt += line + "\r\n";
                                        }
                                        else
                                        {
                                            tmpItem.content += line + "\r\n";
                                        }

                                        // get P/N
                                        if (tmpItem.itemName.Equals("show inventory") && line.Contains("CHASSIS") && partNumber.Equals(""))
                                        {
                                            partNumber = Regex.Split(Methods.RemoveExtraSpaces(line), " ")[1];
                                        }

                                        // get local role
                                        if (tmpItem.itemName.Equals("show chassis ha") && line.Contains("local role:") && localRole.Equals(""))
                                        {
                                            localRole = Regex.Split(Methods.RemoveExtraSpaces(line), "local role: ")[1];
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                } // while
            }
            catch
            {
            }
            sr.Dispose();
        }
        //
        //----------------------------------------------------
        //
        /// <summary>
        /// get a command according to its output header
        /// </summary>
        /// <param name="header"></param>
        /// <returns></returns>
        private string mapHeaderToCommand(string header)
        {
            header = Methods.RemoveExtraSpaces(header);
            header = header.TrimEnd(' ');
            switch (header)
            {
                case "HA state of switch infiniband-default":
                    return "show ib smnodes";

                case "Module Device Fan Speed Status":
                    return "show fan";

                case "Module Status":
                case "Module Power Voltage Current Capacity Grid Status":
                case "Module Power Voltage Current Status":
                case "Module Device Status":
                    return "show power";

                case "Module Sensor CurTemp Status":
                case "Module Component Reg CurTemp Status":
                    return "show temparture";

                case "SX module Version":
                    return "show asic version";

                case "IS4 module Version":
                case "BX module Version":
                    return "show asic-version";

                case "Module Power Meter Reg Expected Actual Status":
                case "Module Power Meter Reg Expected Actual Status High Low":
                    return "show voltage";

                case "Module Type Present Power Fatal reason Reset counter_pwr_on Reset_counter_added Device state":
                case "Module Type Present Power Fatal reason Reset counter_pwr_on Reset_counter_added Device state HW Rev":
                case "| Module | Type |Present|Power|Is Fatal |HW Rev| Device |":
                    return "fae show module";

                case "Module Type Part number Serial Number":
                case "Module Type Part number Serial Number Asic revision":
                    return "show inventory";

                case "Module Type Present Power":
                    return "show module";

                case "chassis ha info":
                    return "show chassis ha";

                case "| ALERTS CONFIGURATION |":
                    return "show health-report";

                default:
                    return header;
            }
        }
        //
        //----------------------------------------------------
        //
    }
}
